/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = t__do_command.c                                     */
/*  NOTE      =                                                    */
/*  DATE      = 2014/12/04 by geyh                                 */
/*******************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <CUnit/Basic.h>
#include <CUnit/CUnit.h>
#include <protobuf-c/protobuf-c.h>

#include "frcomm.h"
#include "frmem.h"
#include "frame.h"
#include "client.pb-c.h"
#include "frsutl.h"
#include "frcmd_server.h"
#include "apmtest_cunit.h"

/*******************************************************************************
*  FUNC     :  把filter命令数据转换成protobuf-c类型的数据
*  ARGS     :  p_st_cmd         命令的格式
*           :  pp_data          转换成功的数据
*           :  p_ui_out         转换成功的数据长度
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :  pp_data需要外面释放
*******************************************************************************/
FR_STATIC int __protobuf_do_pack(Command *p_st_cmd, char **pp_data, unsigned int *p_ui_out)
{
    unsigned int ui_len = 0;
    void *p_out = NULL;

    if (p_st_cmd == NULL)
        return FR_FAIL;

    ui_len = command__get_packed_size(p_st_cmd);
    p_out = frmalloc(ui_len);
    if (p_out == NULL)
        return FR_FAIL;

    command__pack(p_st_cmd, p_out);
    *p_ui_out = ui_len;
    *pp_data = p_out;

    return FR_SUCC;
}

static int __suite_init(void)
{

	return 0;
}

static int __suite_cleanup(void)
{

	return 0;
}

int __do_command(char *p_cmd
                 , int i_cmd_len
                 , char **pp_result
                 , int accept_sock);


//l7
void case1(void)
{
    int i_ret = 0;
    Command *p_st_cmd = NULL;
    L7Command *l7_cmd = NULL;
    L7Setting *l7_settings = NULL;
    char *p_cmd = NULL;
    unsigned int i_cmd_len = 0;
    char *p_result = NULL;
    int accept_sock = 1;

    //设置l7_settings
    l7_settings = malloc(sizeof(L7Setting));
    l7_setting__init(l7_settings);
    l7_settings->has_ip_proto = 1;
    l7_settings->ip_proto = 1;
    l7_settings->has_ip = 1;
    l7_settings->ip = iptools_parse_ipaddr("192.168.1.1");
    l7_settings->port = frstrdup("6536");
    l7_settings->l7_proto = malloc(2);
    snprintf(l7_settings->l7_proto,2,"%s","0");

    //设置l7_cmd
    l7_cmd = malloc(sizeof(L7Command));
    l7_command__init(l7_cmd);
    l7_cmd->action = malloc(strlen("add") + 1);
    snprintf(l7_cmd->action,strlen("add") + 1,"%s","add");
    l7_cmd->n_l7_settings = 1;
    l7_cmd->l7_settings = &l7_settings;

    //设置p_st_cmd
    p_st_cmd = malloc(sizeof(Command));
    command__init(p_st_cmd);
    p_st_cmd->l7_cmd = l7_cmd;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_L7Command;

    i_ret = __protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len);
    if(i_ret != FR_SUCC)
    {
        frfree(l7_settings->l7_proto);
        frfree(l7_settings);
        frfree(l7_cmd->action);
        frfree(l7_cmd);
        frfree(p_st_cmd);
    }

    i_ret = __do_command(p_cmd,i_cmd_len,&p_result, accept_sock);

    CU_ASSERT_EQUAL(i_ret,FR_SUCC);
    CU_ASSERT_PTR_NULL(p_result);

    return;
}

//filter
void case2(void)
{
    int i_ret = 0;
    Command *p_st_cmd = NULL;
    FilterCommand *filter_cmd = NULL;
    Filter *filters = NULL;
    char *p_cmd = NULL;
    unsigned int i_cmd_len = 0;
    char *p_result = NULL;
    int i_size_tmp = 0;
    int accept_sock = 1;

    //设置filters
    filters = malloc(sizeof(Filter));
    filter__init(filters);
    filters->ip_proto = 1;
    i_size_tmp = strlen("192.168.1.1") + 1;
    filters->ip_from = malloc(i_size_tmp);
    snprintf(filters->ip_from,i_size_tmp,"%s","192.168.1.1");

    i_size_tmp = strlen("192.168.1.2") + 1;
    filters->ip_to = malloc(i_size_tmp);
    snprintf(filters->ip_to,i_size_tmp,"%s","192.168.1.2");

    i_size_tmp = strlen("22") + 1;
    filters->port_from = malloc(i_size_tmp);
    snprintf(filters->port_from,i_size_tmp,"%s","22");

    i_size_tmp = strlen("6356") + 1;
    filters->port_to = malloc(i_size_tmp);
    snprintf(filters->port_to,i_size_tmp,"%s","6536");

    i_size_tmp = strlen("60:00:ef:00:ea:56") + 1;
    filters->mac = malloc(i_size_tmp);
    snprintf(filters->mac,i_size_tmp,"%s","60:00:ef:00:ea:56");

    //设置filter_cmd
    filter_cmd = malloc(sizeof(FilterCommand));
    filter_command__init(filter_cmd);
    filter_cmd->action = malloc(strlen("add") + 1);
    snprintf(filter_cmd->action,strlen("add") + 1,"%s","add");
    filter_cmd->n_filters = 1;
    filter_cmd->filters = &filters;

    //设置p_st_cmd
    p_st_cmd = malloc(sizeof(Command));
    command__init(p_st_cmd);
    p_st_cmd->filter_cmd = filter_cmd;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_FilterCommand;

    i_ret = __protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len);
    if(i_ret != FR_SUCC)
    {
        frfree(filters->ip_from);
        frfree(filters->ip_to);
        frfree(filters->port_from);
        frfree(filters->ip_to);
        frfree(filters->mac);
        frfree(filters);
        frfree(filter_cmd->action);
        frfree(filter_cmd);
        frfree(p_st_cmd);

    }

    i_ret = __do_command(p_cmd,i_cmd_len,&p_result, accept_sock);

    CU_ASSERT_EQUAL(i_ret,FR_SUCC);
    CU_ASSERT_PTR_NULL(p_result);


    return;
}


//java
void case3(void)
{
    int i_ret = 0;
    Command *p_st_cmd = NULL;
    JavaCommand *java_cmd = NULL;
    char *p_cmd = NULL;
    unsigned int i_cmd_len = 0;
    char *p_result = NULL;
    int accept_sock = 1;

    //设置java_cmd
    java_cmd = malloc(sizeof(JavaCommand));
    java_command__init(java_cmd);
    java_cmd->family = malloc(strlen("unix") + 1);
    snprintf(java_cmd->family,strlen("unix") + 1,"%s","unix");
    java_cmd->port = frstrdup("22");;

    //设置p_st_cmd
    p_st_cmd = malloc(sizeof(Command));
    command__init(p_st_cmd);
    p_st_cmd->java_cmd = java_cmd;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_JavaCommand;

    i_ret = __protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len);
    if(i_ret != FR_SUCC)
    {
        frfree(java_cmd->family);
        frfree(java_cmd);
        frfree(p_st_cmd);

    }

    i_ret = __do_command(p_cmd,i_cmd_len,&p_result, accept_sock);

    CU_ASSERT_EQUAL(i_ret,FR_SUCC);
    CU_ASSERT_PTR_NULL(p_result);

    return;
}

//commit
void case4(void)
{
    int i_ret = 0;
    Command *p_st_cmd = NULL;
    CommitCommand *commit_cmd = NULL;
    char *p_cmd = NULL;
    unsigned int i_cmd_len = 0;
    char *p_result = NULL;
    int i_size_tmp = 0;
    int accept_sock = 1;

    //设置commit_cmd
    commit_cmd = malloc(sizeof(CommitCommand));
    commit_command__init(commit_cmd);
    commit_cmd->action = COMMIT_COMMAND__ACTION__Commit;
    commit_cmd->cmd = COMMIT_COMMAND__TYPE__MODULE;

    //设置p_st_cmd
    p_st_cmd = malloc(sizeof(Command));
    command__init(p_st_cmd);
    p_st_cmd->commit_cmd = commit_cmd;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_CommitCommand;

    i_ret = __protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len);
    if(i_ret != FR_SUCC)
    {
        frfree(commit_cmd);
        frfree(p_st_cmd);

    }

    i_ret = __do_command(p_cmd,i_cmd_len,&p_result, accept_sock);

    return;
}

//print
void case5(void)
{
    int i_ret = 0;
    Command *p_st_cmd = NULL;
    PrintCommand *print_cmd = NULL;
    char *p_args = NULL;
    char *p_cmd = NULL;
    unsigned int i_cmd_len = 0;
    char *p_result = NULL;
    int i_size_tmp = 0;
    int accept_sock = 1;

    //设置p_args
 /*   i_size_tmp = strlen("system") + 1;
    p_args = malloc(i_size_tmp);
    snprintf(p_args,i_size_tmp,"%s","system");
*/
    //设置print_cmd
    print_cmd = malloc(sizeof(PrintCommand));
    print_command__init(print_cmd);
    print_cmd->n_args = 0;
    print_cmd->cmd = frstrdup("ct");
    print_cmd->args = &p_args;
    i_size_tmp = strlen("all") + 1;
    print_cmd->cmd = malloc(i_size_tmp);
    snprintf(print_cmd->cmd,i_size_tmp,"%s","all");

    //设置p_st_cmd
    p_st_cmd = malloc(sizeof(Command));
    command__init(p_st_cmd);
    p_st_cmd->print_cmd = print_cmd;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_PrintCommand;

    i_ret = __protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len);
    if(i_ret != FR_SUCC)
    {
        frfree(print_cmd->cmd);
        frfree(print_cmd);
        frfree(p_st_cmd);

    }

    i_ret = __do_command(p_cmd,i_cmd_len,&p_result, accept_sock);

    return;
}

//export_cmd
void case6(void)
{
    int i_ret = 0;
    Command *p_st_cmd = NULL;
    ExportCommand *export_cmd = NULL;
    char *p_cmd = NULL;
    unsigned int i_cmd_len = 0;
    char *p_result = NULL;
    int accept_sock = 1;

    //设置export_cmd
    export_cmd = malloc(sizeof(ExportCommand));
    export_command__init(export_cmd);
    export_cmd->ip = iptools_parse_ipaddr("192.168.1.1");
    export_cmd->port = frstrdup("22");

    //设置p_st_cmd
    p_st_cmd = malloc(sizeof(Command));
    command__init(p_st_cmd);
    p_st_cmd->export_cmd = export_cmd;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_ExportCommand;

    i_ret = __protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len);
    if(i_ret != FR_SUCC)
    {
        frfree(export_cmd);
        frfree(p_st_cmd);

    }

    i_ret = __do_command(p_cmd,i_cmd_len,&p_result, accept_sock);

    CU_ASSERT_EQUAL(i_ret,FR_SUCC);
    CU_ASSERT_PTR_NULL(p_result);

    return;
}


//exit
void case7(void)
{
    int i_ret = 0;
    Command *p_st_cmd = NULL;
    char *p_cmd = NULL;
    unsigned int i_cmd_len = 0;
    char *p_result = NULL;
    int accept_sock = 1;


    //设置p_st_cmd
    p_st_cmd = malloc(sizeof(Command));
    command__init(p_st_cmd);
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_ExitCommand;

    i_ret = __protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len);
    if(i_ret != FR_SUCC)
    {
        frfree(p_st_cmd);
    }

    i_ret = __do_command(p_cmd,i_cmd_len,&p_result, accept_sock);

    CU_ASSERT_EQUAL(i_ret,FR_SUCC);
    CU_ASSERT_PTR_NULL(p_result);

    return;
}

//exit
void case8(void)
{
    int i_ret = 0;
    char *p_cmd = NULL;
    unsigned int i_cmd_len = 0;
    char *p_result = NULL;
    int accept_sock = 1;


    i_ret = __do_command(p_cmd,i_cmd_len,&p_result, accept_sock);

    CU_ASSERT_EQUAL(i_ret,FR_FAIL);
    CU_ASSERT_PTR_NULL(p_result);

    return;
}

//COMMAND__COMMAND_TYPE__Type_ModuleCommand
void case9(void)
{
    int i_ret = 0;
    Command *p_st_cmd = NULL;
    ModuleCommand *module_cmd = NULL;
    char *p_cmd = NULL;
    unsigned int i_cmd_len = 0;
    char *p_result = NULL;
    int accept_sock = 1;

    //设置module_cmd
    module_cmd = malloc(sizeof(ModuleCommand));
    module_command__init(module_cmd);
    module_cmd->action = frstrdup("add");
    module_cmd->so_path = frstrdup("so_path");
    module_cmd->l7_proto = 1;
    module_cmd->l4_proto = 6;
    module_cmd->mem_size = 50;
    module_cmd->l7_protoname = frstrdup("l7_protoname");

    //设置p_st_cmd
    p_st_cmd = malloc(sizeof(Command));
    command__init(p_st_cmd);
    p_st_cmd->module_cmd = module_cmd;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_ModuleCommand;

    i_ret = __protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len);
    if(i_ret != FR_SUCC)
    {
        return;
    }

    i_ret = __do_command(p_cmd,i_cmd_len,&p_result, accept_sock);

    CU_ASSERT_EQUAL(i_ret,FR_SUCC);
    CU_ASSERT_PTR_NULL(p_result);

    return;
}

//COMMAND__COMMAND_TYPE__Type_ModuleDefault
void case10(void)
{
    int i_ret = 0;
    Command *p_st_cmd = NULL;
    ModuleDefault *module_default = NULL;
    char *p_cmd = NULL;
    unsigned int i_cmd_len = 0;
    char *p_result = NULL;
    int accept_sock = 1;

    //设置module_default
    module_default = malloc(sizeof(ExportCommand));
    module_default__init(module_default);
    module_default->action = frstrdup("add");
    module_default->ip_proto = 6;
    module_default->l7_proto = 6;

    //设置p_st_cmd
    p_st_cmd = malloc(sizeof(Command));
    command__init(p_st_cmd);
    p_st_cmd->module_default = module_default;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_ModuleDefault;

    i_ret = __protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len);
    if(i_ret != FR_SUCC)
        return;

    i_ret = __do_command(p_cmd,i_cmd_len,&p_result, accept_sock);

    CU_ASSERT_EQUAL(i_ret,FR_SUCC);
    CU_ASSERT_PTR_NULL(p_result);

    return;
}

//COMMAND__COMMAND_TYPE__Type_L7Default
void case11(void)
{
    int i_ret = 0;
    Command *p_st_cmd = NULL;
    L7Default *l7_default = NULL;
    char *p_cmd = NULL;
    unsigned int i_cmd_len = 0;
    char *p_result = NULL;
    int accept_sock = 1;
    L7Setting *l7_settings = NULL;

    //设置l7_settings
    l7_settings = malloc(sizeof(L7Setting));
    l7_setting__init(l7_settings);
    l7_settings->has_ip_proto = 1;
    l7_settings->ip_proto = 1;
    l7_settings->has_ip = 1;
    l7_settings->ip = iptools_parse_ipaddr("192.168.1.1");
    l7_settings->port = frstrdup("6536");
    l7_settings->l7_proto = malloc(2);
    snprintf(l7_settings->l7_proto,2,"%s","0");

    //设置l7_default
    l7_default = malloc(sizeof(L7Default));
    l7_default__init(l7_default);
    l7_default->action = frstrdup("add");
    l7_default->has_mem_size = 1;
    l7_default->mem_size = 50;
    l7_default->n_l7_settings = 1;
    l7_default->l7_settings = &l7_settings;

    //设置p_st_cmd
    p_st_cmd = malloc(sizeof(Command));
    command__init(p_st_cmd);
    p_st_cmd->l7_default = l7_default;
    p_st_cmd->cmd_type = COMMAND__COMMAND_TYPE__Type_L7Default;

    i_ret = __protobuf_do_pack(p_st_cmd,&p_cmd,&i_cmd_len);
    if(i_ret != FR_SUCC)
    {
        return;
    }

    i_ret = __do_command(p_cmd,i_cmd_len,&p_result, accept_sock);

    CU_ASSERT_EQUAL(i_ret,FR_SUCC);
    CU_ASSERT_PTR_NULL(p_result);

    return;
}

int add_suite()
{
	CU_pSuite pSuite = NULL;

	pSuite = CU_add_suite("t__do_command 测试", __suite_init, __suite_cleanup);

	if (NULL == pSuite)
	{
		return 1;
	}


    //增加测试用例
   	CU_add_test(pSuite, "case1", case1);

    CU_add_test(pSuite, "case2", case2);

    CU_add_test(pSuite, "case3", case3);

    CU_add_test(pSuite, "case4", case4);

    CU_add_test(pSuite, "case5", case5);

    CU_add_test(pSuite, "case6", case6);

    CU_add_test(pSuite, "case7", case7);

    CU_add_test(pSuite, "case8", case8);
    CU_add_test(pSuite, "case9", case9);
    CU_add_test(pSuite, "case10", case10);
    CU_add_test(pSuite, "case11", case11);

    return 0;

}

int main(int argc, char **argv)
{
    fr_slab_init(52428800, "test");
    run_cunit(add_suite);
    fr_slab_destroy();

    return 0;
}
